﻿/**
 * @file service_time_scheduler.hpp
 * @date 2021/04/26 20:16
 *
 * @author harrybao (harrybao@123u.com)
 *
 * @brief 服务定时器
 *
 * @version v1.0.0
 *
 * @copyright Copyright © 2021 All Rights Reserved 上海欢乐互娱网络科技有限公司
 *
 * @par history:
 * <table>
 * <tr><th>Date                     <th>Version     <th>Author <th>Description
 * <tr><td>2021/04/26 20:16         <td>1.0.0       <td>harrybao
 * <td>创建初始版本
 * </table>
 */

// #ifndef SERVICE_TIME_SCHEDULER_HPP
// #define SERVICE_TIME_SCHEDULER_HPP

#pragma once

#include <cassert>
#include "box/service_context.hh"
#include "scheduler/scheduler.hh"
#include "service_tool.hpp"
#include "singleton.hpp"


namespace guild_service {
namespace common {

constexpr uint32_t max_schedule_count = 10;

/**
 * @brief 服务定时器类
 *
 */
class service_time_scheduler : public service_tool {
 public:
  using service_context_type = kratos::service::ServiceContext;
  using time_scheduler_ptr_type = kratos::service::SchedulePtr;
  using time_scheduler_callback_type = kratos::service::SchedulerCallback;
  using time_scheduler_handler_type = std::uint64_t;

  service_time_scheduler() : service_tool() {}

  service_time_scheduler(service_context_type *context)
      : service_tool(),
        m_time_scheduler_ptr(std::move(context->new_scheduler())) {}

  virtual ~service_time_scheduler() = default;

 public:
  const time_scheduler_ptr_type &operator->() const {
    return m_time_scheduler_ptr;
  }

  /**
   * @brief 更新
   *
   * @param ms 时间戳
   * @return std::size_t 本次处理的实际数量
   */
  std::size_t update(std::time_t ms) {
    assert(m_time_scheduler_ptr);
    if (!m_time_scheduler_ptr) {
      return 0;
    }
    return m_time_scheduler_ptr->do_schedule(ms, max_schedule_count);
  }

 private:
  /// 定时器指针
  time_scheduler_ptr_type m_time_scheduler_ptr;
};
}  // namespace common

#define ServiceTimeSchedulerSingleton(...) \
  (*common::singleton<common::service_time_scheduler>::instance(__VA_ARGS__))

using time_scheduler_handler_type =
    common::service_time_scheduler::time_scheduler_handler_type;

using time_scheduler_callback_type =
    common::service_time_scheduler::time_scheduler_callback_type;

/// 非法定时器句柄
constexpr time_scheduler_handler_type kInvalidTimeHandler = 0;

/**
 * @brief 开启一个定时器
 *
 * @param duration 定时时间（毫秒）
 * @param cb 回调函数
 * @param udata 用户数据
 * @return std::uint64_t 定时器句柄
 */
inline static time_scheduler_handler_type
time_schedule(std::time_t duration,
              time_scheduler_callback_type cb,
              std::uint64_t udata) {
  return ServiceTimeSchedulerSingleton()->schedule(duration, cb, udata);
}

/**
 * @brief 开启一个循环定时器
 *
 * @param duration 定时时间（毫秒）
 * @param cb 回调函数
 * @param udata 用户数据
 * @return std::uint64_t 定时器句柄
 */
inline static time_scheduler_handler_type time_schedule_many(
    std::time_t duration, time_scheduler_callback_type cb,
    std::uint64_t udata) {
  return ServiceTimeSchedulerSingleton()->schedule_many(duration, cb, udata);
}

/**
 * @brief 关闭一个定时器
 * 
 * @param handler 定时器句柄 
 * @return true 关闭成功
 * @return false 关闭失败
 */
inline static bool time_cancel(
    common::service_time_scheduler::time_scheduler_handler_type handler) {
  return ServiceTimeSchedulerSingleton()->cancel(handler);
}

}  // namespace guild_service

// #endif  // SERVICE_TIME_SCHEDULER_HPP